package gestionCandidats;

import modele.Dossier;
import modele.ComparatorDossierMoyenne;
import modele.ComparatorDossier;
import modele.ComparatorDossierNom;
import modele.Etudiant;
import modele.Fiche;

import javax.swing.AbstractAction;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JTextField;
import javax.swing.JScrollPane;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.DefaultCellEditor;

import javax.swing.table.TableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.AbstractTableModel;

import javax.swing.border.BevelBorder;

import java.awt.event.MouseEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.Component;

import java.util.SortedSet;
import java.util.TreeSet;

public class DossierAfficheAction extends AbstractAction  {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	protected String[] columnToolTips = {
			"<html>Le numero ApoFlux du dossier</html>",
			"<html>Entre crochets le nombre de modifications</html>",
			null,
			"<html>OUI = redoublant</html>",
			"<html>La provenance du candidat</html>",
			"<html>Le dossier est valide ssi dans l'ecran evaluation<ul><li>OK administratif</li><li>Bac+4 acquis</li><li>OK pedagogique</li></ul></html>",
			"<html>Remarques interne. Importees d'Apoflux, modifiables par la suite</html>",
			"<html>La note mise par l'evaluateur</html>",
			"<html>La liste ordonnee des specialites demandees<br>Entre crochets le nombre de modifications</html>",
			"<html>La liste ordonnee des propositions<br>Entre crochets le nombre de propositions faites</html>",
			"<html>La reponse a la derniere proposition</html>"
	};

	protected String[] EnteteEtudiant = {"Date (creation ou derniere modification)",
			"Apoflux",
			"Formation Continue",
			"Etat Civil",
			"Nom",
			"Prenom",
			"e-mail",
			"Telephone",
			"Adresse",
			"Code Postal et Ville",
			"Pays",
			"Redoublant",
			"Etablissement d\'origine",
			"Cursus année actuelle",
			"Cursus année - 1",
			"Cursus année - 2",
			"Cursus année - 3"};
	
	SortedSet<Dossier> lDos;
	GestionCandidats appli;
	JScrollPane scrollpane;
	JPanel vue;
	TableModel dataModel;
	JTable lDossier;
	Point dernierePosition;
	int derniereSelection;
	JComboBox<String> triJCB;
	JTextField filter;
	JLabel status;

	protected DossierAfficheAction(GestionCandidats appli) {
		super("DossierAfficheAction");
		this.appli = appli;
		vue = appli.getDossierAffiche();
		dernierePosition = null;
		derniereSelection = -1;
	}

	public JTable getDossierListe(){
		return lDossier;
	}

	private void trierDossierNom() throws Exception {
		SortedSet<Dossier> aux = new TreeSet<Dossier>(new ComparatorDossierNom());
		for(Dossier dos : lDos)
			aux.add(dos);
		lDos = aux;
	}

	private void trierDossierNoteDossier() throws Exception {
		SortedSet<Dossier> aux = new TreeSet<Dossier>(new ComparatorDossierMoyenne());
		for (Dossier dos : lDos)
			aux.add(dos);
		lDos = aux;
	}

	private void trierFiltrerDossier(String filtre, int modetri) throws Exception {

		if (!filtre.isEmpty() || modetri>=3) {
			SortedSet<Dossier> aux=new TreeSet<Dossier>(new ComparatorDossier());
			String filtrel=filtre.toLowerCase();
			String filtreu=filtre.toUpperCase();
			if (modetri==4) {
				// affiche dossier qui n'ont pas de proposition dans leur spe M1
				for (Dossier dos : lDos) {
					Etudiant etu = dos.getEtudiant();
					String parcours = dos.getPropositionParcours();
					if (!dos.getDemandeListeParcours().equals("[0]") &&
							((etu.getNomCursusAnnée1().equals("M1 Info Bdx1 - AMF") && !parcours.contains("AMF-")) ||
									(etu.getNomCursusAnnée1().equals("M1 Info Bdx1 - GL") && !parcours.contains("GL-")) ||
									(etu.getNomCursusAnnée1().equals("M1 Info Bdx1 - ISV") && !parcours.contains("ISV-")) ||
									(etu.getNomCursusAnnée1().equals("M1 Info Bdx1 - RSM") && !parcours.contains("RSM-"))))
						aux.add(dos);
				}
			} else if (modetri==5) {
				// affiche dossiers avec fiche absente
				for (Dossier dos : lDos) {
					if(dos.getDemande()==null)
						continue;
					for (Fiche fic : dos.getDemande().getFiches()) { 
						if(fic.getAbsente()) {
							aux.add(dos);
							break;
						}
					}
				}
			} 
			else if (modetri==6) {
				// affiche dossier qui n'ont pas encore leur M1
				for (Dossier dos : lDos){
					if (dos.getDemande()!=null && dos.getEvaluation()!=null && !dos.getEvaluation().getMaster1Acquis())
						aux.add(dos);
				}
			} else if (modetri==7) {
				// affiche dossiers avec demandes qui n'ont pas de proposition
				for (Dossier dos : lDos){
					if (dos.getDemande()!=null && dos.getEvaluation()!=null &&
							dos.getEvaluation().getOkAdministratif() && dos.getEvaluation().getOkPedagogique()
							&& dos.getPropositions().size()==0)
						aux.add(dos);
				}
			} else if (modetri==8) {
				// affiche dossier autre que 1er choix
				for (Dossier dos : lDos) {
					//très moche...
					if (dos.getPropositions().size()!=0 &&
							((dos.getDemandeListeParcours().contains("[AMF-")
									&& !dos.getPropositionParcours().contains("]AMF-")) ||
									(dos.getDemandeListeParcours().contains("[RMS-")
											&& !dos.getPropositionParcours().contains("]RSM-")) ||
											(dos.getDemandeListeParcours().contains("[GL-")
													&& !dos.getPropositionParcours().contains("]GL-")) ||
													(dos.getDemandeListeParcours().contains("[ISV-")
															&& !dos.getPropositionParcours().contains("]ISV-"))))
						aux.add(dos);
				}
			} else if (modetri==9) {
				// affiche dossier cas bizarre proposition et note 0
				for (Dossier dos : lDos) {
					if (!dos.getDemandeListeParcours().equals("[0]") && dos.getEvaluation()!=null &&
							((dos.getEvaluation().getNoteDossier()==0.0
									&& dos.getPropositions().size()!=0)))
						// 			 || (dos.getEvaluation().getOkPedagogique() &&
						// 			     dos.getEvaluation().getOkAdministratif() &&
						// 			     !dos.getEvaluation().getMaster1Acquis()
						// 			     && dos.getPropositions().size()==0)));
						aux.add(dos);
				}
			} else if (modetri==10) {
				// affiche dossier cas bizarre BAC+4 non acquis, OK sinon
				for (Dossier dos : lDos) {
					if (!dos.getDemandeListeParcours().equals("[0]") && dos.getEvaluation()!=null &&
							dos.getEvaluation().getOkPedagogique() &&
							dos.getEvaluation().getOkAdministratif() &&
							!dos.getEvaluation().getMaster1Acquis())
						aux.add(dos);
				}
			} else if (modetri==11) {
				// affiche dossier refus administratif
				for (Dossier dos : lDos) {
					if (!dos.getDemandeListeParcours().equals("[0]") && dos.getEvaluation()!=null &&
							!dos.getEvaluation().getOkAdministratif())
						aux.add(dos);
				}
			} else if (modetri==12) {
				// affiche dossier refus administratif
				for (Dossier dos : lDos) {
					if (!dos.getDemandeListeParcours().equals("[0]") && dos.getEvaluation()!=null &&
							!dos.getEvaluation().getOkPedagogique())
						aux.add(dos);
				}
			} else if (modetri==13) {
				// affiche dossier invalides sans remarque / motif de rejet
				for (Dossier dos : lDos) {
					if (!dos.getDemandeListeParcours().equals("[0]") && dos.getEvaluation()!=null &&
							!dos.getEvaluation().isOK() && dos.getEvaluation().getRemarques().equals(""))
						aux.add(dos);
				}
			} else if (modetri==14) {
				// dossier avec proposition sans reponses
				for (Dossier dos : lDos) {
					if (!dos.getDemandeListeParcours().equals("[0]") && dos.getProposition()!=null &&
							!dos.getReponseCoupon().equals("OUI") &&
							!dos.getReponseCoupon().equals("NON") && !dos.getReponseCoupon().equals("OUI +") &&
							!dos.getReponseCoupon().equals("NON +") && !dos.getReponseCoupon().equals("Retire")) {
						// hack pour sortir les adresses email
						aux.add(dos);
						System.out.print(dos.getEtudiant().getEmail() + ",");
					}
				}
				System.out.println();
			} else if (modetri==15) {
				// dossier avec proposition
				for (Dossier dos : lDos) {
					if (!dos.getDemandeListeParcours().equals("[0]") && dos.getProposition()!=null
							&& !dos.getReponseCoupon().equals("Retire")) {
						aux.add(dos);
						// hack pour sortir les adresses email
						System.out.print(dos.getEtudiant().getEmail() + ",");
					}
				}
				System.out.println();
			} else {
				aux=lDos;
			}

			lDos=aux;
			if (modetri == 0 || modetri>=3 )
				aux = new TreeSet<Dossier>(new ComparatorDossier());
			else if (modetri == 1)
				aux = new TreeSet<Dossier>(new ComparatorDossierNom());
			else if (modetri == 2)
				aux = new TreeSet<Dossier>(new ComparatorDossierMoyenne());

			// affiche dossiers contenant texte dans un des champs
			for (Dossier dos : lDos) {
				Etudiant etu = dos.getEtudiant();
				if (etu.getIdApoflux().contains(filtreu) ||
						etu.getNom().contains(filtreu) ||
						etu.getPrenom().toLowerCase().contains(filtrel) ||
						Float.toString(dos.getNoteDossier()).startsWith(filtre) ||
						dos.getPostIt().toLowerCase().contains(filtrel) ||
						etu.getEtablissementOrigine().toLowerCase().contains(filtrel) ||
						dos.getDemandeListeParcours().contains(filtreu) ||
						dos.getPropositionParcours().contains(filtreu) ||
						dos.getEvaluation().getRemarques().toLowerCase().contains(filtrel) ||
						dos.getReponseCoupon().equals(filtre))
					aux.add(dos);
			}
			lDos = aux;
		} else {
			if (modetri == 1)
				trierDossierNom();
			else if (modetri == 2)
				trierDossierNoteDossier();
		}
	}

	private ActionListener trierDossierAction(final DossierAfficheAction daa) {
		ActionListener trierDossierListener = new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					daa.actionPerformed(e);
				}
				catch (Exception ex){
					JOptionPane.showMessageDialog(appli,
							ex.getMessage(), "Tri dossiers : Attention",	JOptionPane.ERROR_MESSAGE);
				}
			}
		};
		return trierDossierListener;
	}

	private Dossier getSelectedDossier(Object ident)
	throws Exception {
		for (Dossier dos : lDos){
			if (dos.getEtudiant().getIdApoflux().equals((String)ident))
				return dos;
		}
		return null;
	}

	public Dossier getSelectedDossier() throws Exception {
		dernierePosition = scrollpane.getViewport().getViewPosition();
		derniereSelection = getDossierListe().getSelectedRow();
		if (derniereSelection != -1)
			return getSelectedDossier(dataModel.getValueAt(derniereSelection,0));
		else
			return null;
	}

	public Component getVue(){
		return vue;
	}

	public void actionPerformed(ActionEvent e) {
		try {
			if(vue == null) {
				vue = new JPanel();
				vue.setLayout(new BorderLayout());
				appli.add(vue,BorderLayout.CENTER);
				scrollpane = new JScrollPane();
				scrollpane.setBorder(new BevelBorder(BevelBorder.LOWERED));
				vue.add(scrollpane,BorderLayout.CENTER);

				JPanel pied = new JPanel();
				vue.add(pied, BorderLayout.SOUTH);

				// ajouter label pour compter dossier et autres infos
				status=new JLabel("Filtre:");
				pied.add(status);

				// ajouter textfield ici et mettre this en action listener
				filter=new JTextField("",12);
				filter.addActionListener(trierDossierAction(this));
				filter.setEditable(true);
				pied.add(filter);

				triJCB = new JComboBox<String>();
				triJCB.addItem("Tri Numero");
				triJCB.addItem("Tri Nom");
				triJCB.addItem("Tri Note");
				triJCB.addItem("-");
				triJCB.addItem("Pas propos. dans spe M1");
				triJCB.addItem("Fiche absente");
				triJCB.addItem("BAC+4 non acquis");
				triJCB.addItem("Dossiers sans propos.");
				triJCB.addItem("Prop autre que 1er choix");
				triJCB.addItem("Bizarre: prop et note 0");
				triJCB.addItem("Refus que BAC+4 non acq");
				triJCB.addItem("Refus administratif");
				triJCB.addItem("Refus pedagogique");
				triJCB.addItem("Refus non motive");
				triJCB.addItem("Propos. sans reponse");
				triJCB.addItem("Propositions en cours");
				triJCB.setSelectedIndex(0);
				triJCB.addActionListener(trierDossierAction(this));
				pied.add(triJCB);
				JButton retour = new JButton("Fermer");
				retour.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						vue.setVisible(false);
					}
				});
				pied.add(retour);
				JButton details = new JButton("Détails");
				details.addActionListener(new EtudiantAfficheAction(appli,this));
				pied.add(details);
				JButton evaluation = new JButton("Evaluation");
				evaluation.
				addActionListener(new EvaluationAfficheAction(appli,this));
				pied.add(evaluation);
			}

			lDos = appli.getBd().getDossiers();
			trierFiltrerDossier(filter.getText(), triJCB.getSelectedIndex());
			status.setText(lDos.size()+" dossiers. Filtre:");
			derniereSelection = -1;
			
			final String entete[] = {"Apoflux", "Nom", "Prenom", "Redoublant", "Origine", "Valide", "PostIt", "Note", "Demande", "Proposition", "Reponse"};
			final Object[][] data = new Object[lDos.size()][entete.length];
			int i = 0;
			for (Dossier dos : lDos) {
				Etudiant etu = dos.getEtudiant();
				data[i][0] = etu.getIdApoflux();
				data[i][1] = etu.getNom();
				data[i][2] = etu.getPrenom();
				data[i][3] = etu.getRedoublant();
				data[i][4] = etu.getEtablissementOrigine();
				data[i][5] = dos.getRecevable();
				data[i][6] = dos.getPostIt();
				data[i][7] = dos.getNoteDossier();
				data[i][8] = dos.getDemandeListeParcours();
				data[i][9] = dos.getPropositionParcours();
				data[i][10] = dos.getReponseCoupon();
				i++;
			}
			// Create a model of the data.
			dataModel = new AbstractTableModel() {
				/**
				 * Affichage de la liste des dossiers
				 */
				
				private static final long serialVersionUID = 1L;
				// These methods always need to be implemented.
				public int getColumnCount() { return entete.length; }
				public int getRowCount() { return lDos.size();}
				public Object getValueAt(int row, int col) {
					return data[row][col];
				}
				public void setValueAt(Object aValue, int row, int column){
					data[row][column] = aValue;
					try {
						if (column==10)
							getSelectedDossier(data[row][0]).
							setReponseCoupon((String)aValue);
						if (column==6)
							getSelectedDossier(data[row][0]).
							setPostIt((String)aValue);
					}
					catch (Exception ex){}
				}
				public String getColumnName(int column) {
					
					return entete[column];
				}
				@SuppressWarnings({ "unchecked", "rawtypes" })
				public Class getColumnClass(int c) {
					return getValueAt(0, c).getClass();
				}
				public boolean isCellEditable(int row, int col) {
					return (col==6)||(col==10);
				}
			};
			// Create the table
			lDossier = new JTable(dataModel){
				/**
				 * 
				 */
				private static final long serialVersionUID = 1L;

				protected JTableHeader createDefaultTableHeader(){
					return new JTableHeader(columnModel) {
						/**
						 * 
						 */
						private static final long serialVersionUID = 1L;

						public String getToolTipText(MouseEvent e){
							//  String tip = null;
							java.awt.Point p = e.getPoint();
							int index = columnModel.
							getColumnIndexAtX(p.x);
							int realIndex = columnModel.
							getColumn(index).
							getModelIndex();
							return columnToolTips[realIndex];
						}
					};
				}
			};
			lDossier.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
			lDossier.setRowHeight(2*lDossier.getRowHeight());
			// Finish setting up the table.

			JComboBox<String> couponJCB = new JComboBox<String>();
			couponJCB.addItem("OUI +");
			couponJCB.addItem("OUI");
			couponJCB.addItem("NON +");
			couponJCB.addItem("Retire");
			couponJCB.addItem("-");
			TableColumn couponTC = lDossier.getColumn(entete[10]);
			couponTC.setCellEditor(new DefaultCellEditor(couponJCB));


			DefaultTableCellRenderer couponTCRenderer = new DefaultTableCellRenderer() {
				/**
				 * 
				 */
				private static final long serialVersionUID = 1L;

				public void setValue(Object value) {
					setBackground(GestionCandidats.colorModif);
					setText(value.toString());
				}
			};
			couponTCRenderer.setHorizontalAlignment(JLabel.CENTER);
			couponTC.setCellRenderer(couponTCRenderer);

			scrollpane.setViewportView(lDossier);

			// JS 2009/06/24: code probablement inutile sauf si on
			// retrouve index a partir de dossier. derniereSelection
			// force a -1 pour l'instant
			if (derniereSelection != -1)
				lDossier.setRowSelectionInterval(derniereSelection,derniereSelection);
			if (dernierePosition != null)
				scrollpane.getViewport().setViewPosition(dernierePosition);

			vue.setVisible(true);
			appli.getFrame().setVisible(true);
		}
		catch(Exception ex){
			ex.printStackTrace();
			JOptionPane.showMessageDialog
			(appli, ex.getMessage(), "Affichage des dossiers : Attention",
					JOptionPane.ERROR_MESSAGE);
		}
	}
}

